/******************************************************************************* * Copyright (c) 2009 EclipseSource and others. All rights reserved. This * program and the accompanying materials are made available under the terms of * the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * EclipseSource - initial API and implementation *******************************************************************************/ package org.eclipse.rap.ui.interactiondesign; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.rap.ui.interactiondesign.internal.ConfigurableStackProxy; import org.eclipse.rap.ui.internal.branding.BrandingUtil; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.ui.internal.LayoutPart; import org.eclipse.ui.internal.WorkbenchWindow; import org.eclipse.ui.internal.presentations.PresentablePart; import org.eclipse.ui.internal.util.PrefUtil; import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.eclipse.ui.presentations.IPresentablePart; import org.eclipse.ui.presentations.IStackPresentationSite; import org.eclipse.ui.presentations.StackPresentation; /** * This represents an object to configure different part properties e.g. * toolitem visibility, viewmenu visibility or the * <code>{@link ConfigurableStack}</code> for a selected part. * <p> * This is a ordinary <code>{@link Action}</code>. The * <code>{@link #run()}</code> method can implement any configuration behaviour * e.g. a PupupDialog. * </p> * <p> * Additional this class provides methods for saving and laoding some * presentation specific properties. * </p> * * @since 1.2 * @see Action * @see ConfigurableStack */ public abstract class ConfigurationAction extends Action { public ConfigurationAction() { allActionsVisible = allActionsVisible(); } /** * Extracts the id of an <code>{@link ActionContributionItem}</code> from a * <code>{@link ToolItem}</code>. * @param item the <code>ToolItem</code>, which holds a * <code>ActionContributionItem</code>. * * @return the extracted id of an */ public static final String getActionIdFromToolItem( final ToolItem item ) { String result = ""; Object data = item.getData(); ActionContributionItem toolBarAction = ( ActionContributionItem )data; result = toolBarAction.getId(); return result; } private IStackPresentationSite site; private StackPresentation stackPresentation; private List configurationChangeListeners = new ArrayList(); private boolean allActionsVisible; /** * Helper method to check if all view contrib items are visible by default. * @return true if all items are visible by default. */ public static boolean allActionsVisible() { boolean result = false; String brandingId = BrandingUtil.getCurrentBrandingId(); if( brandingId != null ) { IExtensionRegistry registry = Platform.getExtensionRegistry(); final String id = "org.eclipse.rap.ui.branding"; IExtensionPoint brandingPoint = registry.getExtensionPoint( id ); if( brandingPoint != null ) { IConfigurationElement[] elements = brandingPoint.getConfigurationElements(); boolean found = false; for( int i = 0; i < elements.length && !found; i++ ) { String tempId = elements[ i ].getAttribute( "id" ); if( tempId.equals( brandingId ) ) { found = true; IConfigurationElement[] factory = elements[ i ].getChildren( "presentationFactory" ); if( factory.length > 0 ) { String visibility = factory[ 0 ].getAttribute( "viewActionsVisible" ); if( visibility != null && Boolean.valueOf( visibility ).booleanValue() ) { result = true; } } } } } } return result; } /** * Method to add a <code>{@link IConfigurationChangeListener}. * @param listener an instance of a <code>IConfigurationChangedListener * </code>. * * @see IConfigurationChangeListener */ public void addConfigurationChangeListener( final IConfigurationChangeListener listener ) { configurationChangeListeners.add( listener ); } /** * This method is called if the <code>{@link ConfigurableStack}</code> of a * part has changed. It just calls the * <code>{@link IConfigurationChangeListener#presentationChanged(String)} * </code> method for all listeners added by * <code>{@link #addConfigurationChangeListener(IConfigurationChangeListener)} * </code>. * * @param newId the new <code>ConfigurableStack</code> id to make active. * * @see ConfigurableStack * @see IConfigurationChangeListener */ public void fireLayoutChange( final String newId ) { for( int i = 0; i < configurationChangeListeners.size(); i++ ) { IConfigurationChangeListener listener = ( IConfigurationChangeListener )configurationChangeListeners.get( i ); listener.presentationChanged( newId ); } } /** * This method can be called if the configuration of the view's toolbar has * been changed. It calls * <code>{@link IConfigurationChangeListener#toolBarChanged()}</code> for all * listeners registered by * <code>{@link #addConfigurationChangeListener(IConfigurationChangeListener)} * </code>. * * @see IConfigurationChangeListener */ public void fireToolBarChange() { for( int i = 0; i < configurationChangeListeners.size(); i++ ) { IConfigurationChangeListener listener = ( IConfigurationChangeListener )configurationChangeListeners.get( i ); listener.toolBarChanged(); } } private String getActionIdentifier( final String viewId, final String actionId ) { return ConfigurableStackProxy.STACK_PRESENTATION_ID + "/" + viewId + "/" + actionId; } private String getPartMenuIdentifier( final String paneId ) { return ConfigurableStackProxy.STACK_PRESENTATION_ID + "/" + paneId + "/partMenu"; } /** * This method returns the <code>IStackPresentationSite</code> from the * <code>StackPresentation</code>, which belongs to this * <code>ConfigurationAction</code>. * @return the <code>IStackPresentationSite</code> to communicate with the * part. */ public IStackPresentationSite getSite() { return site; } /** * Return the <code>{@link StackPresentation}</code>, which this action * belongs to. * * @return the <code>StackPresentation</code> object. * * @see ConfigurableStack */ public StackPresentation getStackPresentation() { return stackPresentation; } /** * Checks if the selected part has a menu or not. * * @return <code>true</code> if the selected part has a menu. */ public boolean hasPartMenu() { boolean result = false; IPresentablePart selectedPart = site.getSelectedPart(); if( selectedPart instanceof PresentablePart ) { PresentablePart part = ( PresentablePart )selectedPart; result = part.getPane().hasViewMenu(); } return result; } /** * This method is called right after the object is instantiated to set * different fields. These fields are necessary to get the needed * information about the current <code>{@link WorkbenchWindow}</code> state * e.g. the selected part or the current <code>{@link ConfigurableStack} * </code>. * * @param site the site used for communication between the presentation and * the workbench. * @param stackPresentation the current <code>{@link StackPresentation}</code> * or <code>ConfigurableStack</code> to get the part's toolbar and so on. * * @see ConfigurableStack * @see IStackPresentationSite * @see StackPresentation */ public void init( final IStackPresentationSite site, final StackPresentation stackPresentation ) { this.site = site; this.stackPresentation = stackPresentation; } /** * Check if the part menu is set visible by the user. * * @return the visibility of the part menu. */ public boolean isPartMenuVisible() { boolean result = true; if( !allActionsVisible) { if( stackPresentation instanceof ConfigurableStack ) { ConfigurableStack configStack = ( ConfigurableStack )stackPresentation; String paneId = configStack.getPaneId( site ); String identifier = getPartMenuIdentifier( paneId ); result = loadPartmenuVisibility( identifier ); } } return result; } private boolean loadPartmenuVisibility( final String identifier ) { boolean result = false; IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore(); result = preferenceStore.getBoolean( identifier ); return result; } /** * Returns the visibility for an <code>{@link ActionContributionItem}</code>, * which is contributed to a view's toolbar. By default all <code> * ActionContributionItem</code>s are not visible. The visibility is stored * in a <code>ScopedPreferenceStore</code>. * * @param viewId the id of the view that holds the * <code>ActionContributionItem</code>. * @param actionId the unique id of the <code>{@link Action}</code> holding by * an <code>ActionContributionItem</code>. * * @return the visibility of the <code>ActionContributionItem</code>. If no * value is stored, the default value is <code>false</code>. * * @see ActionContributionItem * @see Action * @see ScopedPreferenceStore */ public boolean isViewActionVisibile( final String viewId, final String actionId ) { boolean result = true; if( !allActionsVisible ) { String identifier = getActionIdentifier( viewId, actionId ); ScopedPreferenceStore prefStore = ( ScopedPreferenceStore ) PrefUtil.getAPIPreferenceStore(); result = prefStore.getBoolean( identifier ); } return result; } /** * Removes a <code>{@link IConfigurationChangeListener}</code> from this * action. * * @param listener the <code>IConfigurationChangeListener</code> to remove. */ public void removeLayoutChangeListener( final IConfigurationChangeListener listener ) { boolean found = false; for( int i = 0; !found && i < configurationChangeListeners.size(); i++ ) { IConfigurationChangeListener current = ( IConfigurationChangeListener )configurationChangeListeners.get( i ); if( current.equals( listener ) ) { configurationChangeListeners.remove( i ); found = true; } } } /** * Saves the visibility of a part's menu in a * <code>{@link ScopedPreferenceStore}</code>. * * @param visible the new visibility to save. * * @see ScopedPreferenceStore */ public void savePartMenuVisibility( final boolean visible ) { IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore(); if( stackPresentation instanceof ConfigurableStack ) { ConfigurableStack configStack = ( ConfigurableStack )stackPresentation; String paneId = configStack.getPaneId( site ); String identifier = getPartMenuIdentifier( paneId ); preferenceStore.setValue( identifier, visible ); } } /** * Saves the <code>{@link ConfigurableStack}</code> id for the selected * <code>{@link LayoutPart}</code>. * * @param id the unique id of the <code>ConfigurableStack</code> to save. * * @see LayoutPart * @see ConfigurableStack */ public void saveStackPresentationId( final String id ) { if( stackPresentation instanceof ConfigurableStack ) { String layoutPartId = ConfigurableStack.getLayoutPartId( site ); if( site != null && layoutPartId != null ) { ScopedPreferenceStore prefStore = ( ScopedPreferenceStore )PrefUtil.getAPIPreferenceStore(); prefStore.setValue( ConfigurableStackProxy.STACK_PRESENTATION_ID + "/" + layoutPartId, id ); } } } /** * Saves the visibility of a view action in a * <code>{@link ScopedPreferenceStore}</code>. * * @param viewId the id of the view, which holds the view's * <code>{@link ActionContributionItem}</code> * @param actionId the id of the <code>ActionContributionItem</code>, which * the new visibility belongs to. * @param visibility the value of the visibility. */ public void saveViewActionVisibility( final String viewId, final String actionId, final boolean visibility ) { String identifier = getActionIdentifier( viewId, actionId ); ScopedPreferenceStore prefStore = ( ScopedPreferenceStore )PrefUtil.getAPIPreferenceStore(); prefStore.setValue( identifier, visibility ); } }